package com.quick.task;

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;

import java.util.Random;
import java.util.concurrent.Future;

/**
 * @ClassName Task
 * @Description 测试@Async
 * @Author wangxin332
 * @Date 2018/12/1 下午7:57
 * @Version 1.0
 **/
@Component
@Slf4j
public class Task {
	public static Random random =new Random();

	@Async
	public void taskOne () throws Exception{
		System.out.println("开始做任务一");
		long start = System.currentTimeMillis();
		Thread.sleep(random.nextInt(10000));
		long end = System.currentTimeMillis();
		System.out.println("完成任务一，耗时：" + (end - start) + "毫秒");
	}

	@Async
	public void taskTwo() throws Exception {
		System.out.println("开始做任务二");
		long start = System.currentTimeMillis();
		Thread.sleep(random.nextInt(10000));
		long end = System.currentTimeMillis();
		System.out.println("完成任务二，耗时：" + (end - start) + "毫秒");
	}

	@Async
	public void taskThree() throws Exception {
		System.out.println("开始做任务三");
		long start = System.currentTimeMillis();
		Thread.sleep(random.nextInt(10000));
		long end = System.currentTimeMillis();
		System.out.println("完成任务三，耗时：" + (end - start) + "毫秒");
	}



	@Async
	public Future<String> doOne() throws Exception{
		System.out.println("开始做任务一");
		long start = System.currentTimeMillis();
		Thread.sleep(random.nextInt(10000));
		long end = System.currentTimeMillis();
		System.out.println("完成任务一，耗时：" + (end - start) + "毫秒");
		return new AsyncResult<>("任务1完成");
	}

	@Async
	public Future<String> doTwo() throws Exception{
		System.out.println("开始做任务二");
		long start = System.currentTimeMillis();
		Thread.sleep(random.nextInt(10000));
		long end = System.currentTimeMillis();
		System.out.println("完成任务二，耗时：" + (end - start) + "毫秒");
		return new AsyncResult<>("任务2完成");
	}
	@Async
	public Future<String> doThree() throws Exception{
		System.out.println("开始做任务三");
		long start = System.currentTimeMillis();
		Thread.sleep(random.nextInt(10000));
		long end = System.currentTimeMillis();
		System.out.println("完成任务三，耗时：" + (end - start) + "毫秒");
		return new AsyncResult<>("任务3完成");
	}


	@Async("taskExecutor")
	public void doTaskOne() throws Exception {
		log.info("开始做任务一");
		long start = System.currentTimeMillis();
		Thread.sleep(random.nextInt(10000));
		long end = System.currentTimeMillis();
		log.info("完成任务一，耗时：" + (end - start) + "毫秒");
	}
	@Async("taskExecutor")
	public void doTaskTwo() throws Exception {
		log.info("开始做任务二");
		long start = System.currentTimeMillis();
		Thread.sleep(random.nextInt(10000));
		long end = System.currentTimeMillis();
		log.info("完成任务二，耗时：" + (end - start) + "毫秒");
	}

	@Async("taskExecutor")
	public void doTaskThree() throws Exception {
		log.info("开始做任务三");
		long start = System.currentTimeMillis();
		Thread.sleep(random.nextInt(10000));
		long end = System.currentTimeMillis();
		log.info("完成任务三，耗时：" + (end - start) + "毫秒");
	}

	/**
	 * future接口说明
	 * 1、cancel方法用来取消任务，如果取消任务成功则返回true，如果取消任务失败则返回false。
	 * 参数mayInterruptIfRunning表示是否允许取消正在执行却没有执行完毕的任务，如果设置true，
	 * 则表示可以取消正在执行过程中的任务。如果任务已经完成，则无论mayInterruptIfRunning为true还是false，
	 * 此方法肯定返回false，即如果取消已经完成的任务会返回false；
	 * 如果任务正在执行，若mayInterruptIfRunning设置为true，则返回true，
	 * 若mayInterruptIfRunning设置为false，则返回false；
	 * 如果任务还没有执行，则无论mayInterruptIfRunning为true还是false，肯定返回true。
	 * 2、isCancelled方法表示任务是否被取消成功，如果在任务正常完成前被取消成功，则返回 true。
	 * 3、isDone方法表示任务是否已经完成，若任务完成，则返回true；
	 * 4、get()方法用来获取执行结果，这个方法会产生阻塞，会一直等到任务执行完毕才返回；
	 * 5、get(long timeout, TimeUnit unit)用来获取执行结果，如果在指定时间内，还没获取到结果，就直接返回null。
	 *
	 * 也就是说Future提供了三种功能：
	 * 1、判断任务是否完成；
	 * 2、能够中断任务；
	 * 3、能够获取任务执行结果。
	 * @return
	 * @throws Exception
	 */
	@Async("taskExecutor")
	public Future<String> run() throws Exception{
		long sleep = random.nextInt(10000);
		log.info("开始任务，需耗时：" + sleep + "毫秒");
		Thread.sleep(sleep);
		log.info("完成任务");
		return new AsyncResult<>("test");
	}
}
